#!/usr/bin/env python3
"""
价格格式化工具模块
实现股票价格的精确格式化，支持截断到指定小数位数（不四舍五入）
"""

import math
from typing import Union

def truncate_to_decimals(value: Union[float, str], decimals: int = 3) -> float:
    """
    截断数值到指定小数位数（不四舍五入）
    
    Args:
        value: 要处理的数值
        decimals: 保留的小数位数，默认3位
        
    Returns:
        float: 截断后的数值
    """
    try:
        # 转换为浮点数
        if isinstance(value, str):
            num = float(value)
        else:
            num = float(value)
        
        # 使用数学方法截断，不四舍五入
        multiplier = 10 ** decimals
        truncated = math.trunc(num * multiplier) / multiplier
        
        return truncated
    except (ValueError, TypeError):
        return 0.0

def is_etf_stock(stock_code: str) -> bool:
    """
    判断是否为ETF类股票
    
    Args:
        stock_code: 股票代码
        
    Returns:
        bool: 是否为ETF
    """
    if not stock_code:
        return False
    
    # 去除可能的前缀
    code = stock_code.replace('sh', '').replace('sz', '').strip()
    
    # ETF识别规则
    etf_patterns = [
        # 场内ETF代码规则
        lambda c: c.startswith('51'),    # 上交所ETF (510xxx, 511xxx, 512xxx等)
        lambda c: c.startswith('15'),    # 深交所ETF (159xxx)
        lambda c: c.startswith('16'),    # 深交所ETF (160xxx)
        lambda c: c.startswith('50'),    # 上交所50ETF等
        # 特殊ETF代码
        lambda c: c in ['588000', '588080', '588090'],  # 科创50ETF等
    ]
    
    return any(pattern(code) for pattern in etf_patterns)

def get_optimal_decimals(stock_code: str = None, stock_name: str = None) -> int:
    """
    根据股票类型获取最优小数位数
    
    Args:
        stock_code: 股票代码
        stock_name: 股票名称
        
    Returns:
        int: 推荐的小数位数
    """
    # 优先通过代码判断
    if stock_code and is_etf_stock(stock_code):
        return 3
    
    # 通过名称判断
    if stock_name:
        etf_keywords = ['ETF', 'etf', '基金', 'LOF', 'lof']
        if any(keyword in stock_name for keyword in etf_keywords):
            return 3
    
    # 默认为普通股票
    return 2

def format_price(value: Union[float, str], decimals: int = None, stock_code: str = None, stock_name: str = None) -> str:
    """
    格式化价格显示，截断到指定小数位数
    
    Args:
        value: 价格数值
        decimals: 小数位数，如果不指定则自动判断
        stock_code: 股票代码，用于自动判断小数位数
        stock_name: 股票名称，用于自动判断小数位数
        
    Returns:
        str: 格式化后的价格字符串
    """
    if decimals is None:
        decimals = get_optimal_decimals(stock_code, stock_name)
    
    truncated_value = truncate_to_decimals(value, decimals)
    return f"{truncated_value:.{decimals}f}"

def format_price_with_currency(value: Union[float, str], currency: str = "¥", decimals: int = None, stock_code: str = None, stock_name: str = None) -> str:
    """
    格式化价格显示，包含货币符号
    
    Args:
        value: 价格数值
        currency: 货币符号，默认"¥"
        decimals: 小数位数，如果不指定则自动判断
        stock_code: 股票代码，用于自动判断小数位数
        stock_name: 股票名称，用于自动判断小数位数
        
    Returns:
        str: 格式化后的价格字符串（含货币符号）
    """
    price_str = format_price(value, decimals, stock_code, stock_name)
    return f"{currency}{price_str}"

def format_change_percent(value: Union[float, str], decimals: int = None, stock_code: str = None, stock_name: str = None) -> str:
    """
    格式化涨跌幅百分比
    
    Args:
        value: 百分比数值
        decimals: 小数位数，如果不指定则自动判断
        stock_code: 股票代码，用于自动判断小数位数
        stock_name: 股票名称，用于自动判断小数位数
        
    Returns:
        str: 格式化后的百分比字符串
    """
    if decimals is None:
        decimals = get_optimal_decimals(stock_code, stock_name)
    
    truncated_value = truncate_to_decimals(value, decimals)
    
    if truncated_value > 0:
        return f"+{truncated_value:.{decimals}f}%"
    elif truncated_value < 0:
        return f"{truncated_value:.{decimals}f}%"  # 负数本身包含负号
    else:
        return f"{0:.{decimals}f}%"

def format_change_amount(value: Union[float, str], decimals: int = None, stock_code: str = None, stock_name: str = None) -> str:
    """
    格式化涨跌金额
    
    Args:
        value: 涨跌金额
        decimals: 小数位数，如果不指定则自动判断
        stock_code: 股票代码，用于自动判断小数位数
        stock_name: 股票名称，用于自动判断小数位数
        
    Returns:
        str: 格式化后的涨跌金额字符串
    """
    if decimals is None:
        decimals = get_optimal_decimals(stock_code, stock_name)
    
    truncated_value = truncate_to_decimals(value, decimals)
    
    if truncated_value > 0:
        return f"+{truncated_value:.{decimals}f}"
    elif truncated_value < 0:
        return f"{truncated_value:.{decimals}f}"  # 负数本身包含负号
    else:
        return f"{0:.{decimals}f}"

# 测试函数
if __name__ == "__main__":
    print("价格格式化工具测试:")
    print("=" * 50)
    
    # 测试ETF识别
    test_stocks = [
        ("512660", "军工ETF"),      # ETF
        ("510300", "沪深300ETF"),   # ETF
        ("159922", "中证500ETF"),   # ETF
        ("000001", "平安银行"),      # 普通股票
        ("600519", "贵州茅台"),      # 普通股票
        ("300034", "钢研高纳"),      # 普通股票
    ]
    
    print("📊 ETF识别测试:")
    for code, name in test_stocks:
        is_etf = is_etf_stock(code)
        decimals = get_optimal_decimals(code, name)
        print(f"  {code} {name}: {'ETF' if is_etf else '普通股票'} -> {decimals}位小数")
    print()
    
    # 测试价格格式化
    test_values = [
        12.3456789,
        12.3446789,  # 第4位是4，不应该进位
        12.3996789,  # 第4位是9，不应该进位
        0.1236789,
        123.9999,
        -5.6789,
        "15.4567"
    ]
    
    print("📈 价格格式化测试:")
    for value in test_values:
        print(f"原始值: {value}")
        print(f"  ETF格式: {format_price(value, stock_code='512660')}")  # ETF，3位小数
        print(f"  普通股票: {format_price(value, stock_code='000001')}")  # 普通股票，2位小数
        print(f"  自动判断: {format_price(value)}")  # 默认2位小数
        print() 